/* Copyright (c) 2004-2024 Peigen.info. All rights reserved. */

package info.peigen.hotpot.component.gateway.dianlan.processor;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import info.peigen.hotpot.common.core.result.ResultCode;
import info.peigen.hotpot.common.service.base.exception.BusinessException;
import info.peigen.hotpot.component.gateway.dianlan.facade.enums.DianlanFrameSign;
import info.peigen.hotpot.component.gateway.dianlan.processor.business.*;
import info.peigen.hotpot.component.gateway.dianlan.protocol.Dianlan;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.smartboot.socket.MessageProcessor;
import org.smartboot.socket.StateMachineEnum;
import org.smartboot.socket.transport.AioSession;

/**
 * <b>(DianlanSocketServerProcessor)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2022/8/23
 */
@Component("dianlanSocketServerProcessor")
@Slf4j
public class DianlanSocketServerProcessor<T> implements MessageProcessor<T> {
    @Inject
    DianlanLoginProcessor                               dianlanLoginProcessor;
    @Inject
    DianlanHeartProcessor                               dianlanHeartProcessor;
    @Inject
    DianlanChargeFinishProcessor                        dianlanChargeFinishProcessor;
    @Inject
    DianlanSettingTimeProcessor                         dianlanSettingTimeProcessor;
    @Inject
    DianlanStatusPushProcessor                          dianlanStatusPushProcessor;
    @Inject
    DianlanChargeResponseProcessor                      dianlanChargeResponseProcessor;
    @Inject
    DianlanStopChargeResponseProcessor                  dianlanStopChargeResponseProcessor;
    @Inject
    DianlanStubAwaitResponseProcessor                   dianlanStubAwaitResponseProcessor;
    @Inject
    DianlanStubArmResponseProcessor                     dianlanStubArmResponseProcessor;
    @Inject
    DianlanStubSpearHeadResponseProcessor               dianlanStubSpearHeadResponseProcessor;
    @Inject
    DianlanStubBmsAndLiquidCoolingUnitResponseProcessor dianlanStubBmsAndLiquidCoolingUnitResponseProcessor;
    @Inject
    DianlanFireUnitStatusAlarmResponseProcessor         dianlanFireUnitStatusAlarmResponseProcessor;
    @Inject
    DianlanTransInformationProcessor                    dianlanTransInformationProcessor;
    @Inject
    DianlanBillingModelSettingProcessor                 dianlanBillingModelSettingProcessor;
    @Inject
    DianlanBiilingModelCheckProcessor                   dianlanBiilingModelCheckProcessor;
    @Inject
    DianlanRechargeResponseProcessor                    dianlanRechargeResponseProcessor;
    @Inject
    DianlanSettingCardResponseProcessor                 dianlanSettingCardResponseProcessor;

    @Override
    public void process(AioSession session, Object obj) {
        Assert.notNull(obj, () -> new BusinessException(ResultCode.FAILURE, "点蓝网关对象不得为空[obj=" + obj + "]"));
        Dianlan dianlan = (Dianlan) obj;
        check(dianlan);
        choose(session, dianlan);
    }

    @Override
    public void stateEvent(AioSession session, StateMachineEnum stateMachineEnum, Throwable throwable) {

        MessageProcessor.super.stateEvent(session, stateMachineEnum, throwable);
    }

    public void check(Dianlan dianlan) {
        String check = dianlan.check();
        Assert.isTrue(StrUtil.equals(check, dianlan.getFrameCheck()), () -> new BusinessException("帧校验域监测失败"));
    }

    /**
     * 点蓝调用我方接口
     *
     * @param session AioSession
     * @param dianlan Dianlan
     */
    private void choose(AioSession session, Dianlan dianlan) {
        // TODO 上线则删除该判断
        if (dianlan.getFrameSign() != DianlanFrameSign.HeartBeat) {
            log.info("收到设备信息：{}", dianlan.getFrameSign().getMessage());
            log.info(JSON.toJSONString(dianlan));
        }
        switch (dianlan.getFrameSign()) {
            case Login:
                // 登录
                dianlanLoginProcessor.process(session, dianlan);
                break;
            case HeartBeat:
                // 心跳
                dianlanHeartProcessor.process(session, dianlan);
                break;
            case SettingTimeResponse:
                // 对时
                dianlanSettingTimeProcessor.process(session, dianlan);
                break;
            // 充值应答
            case RechargeResponse:
                dianlanRechargeResponseProcessor.process(session, dianlan);
                break;
            // 计费模型设置
            case BillingModelSettingResponse:
                dianlanBillingModelSettingProcessor.process(session, dianlan);
                break;
            // 计费模型验证
            case BillingModelCheck:
                dianlanBiilingModelCheckProcessor.process(session, dianlan);
                break;
            // 设置卡号应答
            case SettingCardResponse:
                dianlanSettingCardResponseProcessor.process(session, dianlan);
                break;
            case StubStatusPush:
                // 充电监测数据推送
                dianlanStatusPushProcessor.process(session, dianlan);
                break;
            case StartChargeResponse:
                // 开始充电应答
                dianlanChargeResponseProcessor.process(session, dianlan);
                break;
            // 交易记录
            case TransInformation:
                dianlanTransInformationProcessor.process(session, dianlan);
                break;
            case StopChargeResponse:
                // 停止充电应答
                dianlanStopChargeResponseProcessor.process(session, dianlan);
                break;
            case StubStopCharge:
                // 主动发送停止充电
                dianlanChargeFinishProcessor.process(session, dianlan);
                break;
            case StubAwaitResponse:
                // 电桩待命应答
                dianlanStubAwaitResponseProcessor.process(session, dianlan);
                break;
            case StubArmResponse:
                // 机械臂应答
                dianlanStubArmResponseProcessor.process(session, dianlan);
                break;
            case StubSpearHeadResponse:
                // 枪头应答
                dianlanStubSpearHeadResponseProcessor.process(session, dianlan);
                break;
            case BmsAndLiquidCoolingUnit:
                // 电池组应答
                dianlanStubBmsAndLiquidCoolingUnitResponseProcessor.process(session, dianlan);
                break;
            // 灭火器
            case FireUnitStatusAlarm:
                dianlanFireUnitStatusAlarmResponseProcessor.process(session, dianlan);
                break;
            default:
                log.info("未知协议：" + JSON.toJSONString(dianlan));
                break;
        }
    }
}